package org.xiaov.framework.util;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.aliyun.oss.ClientBuilderConfiguration;
import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.aliyun.oss.model.PutObjectRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import org.xiaov.framework.component.SpringContext;
import org.xiaov.framework.component.properties.UploadOssProperties;
import org.xiaov.framework.exception.BizException;

import java.io.File;
import java.io.IOException;
import java.util.Date;

/**
 * <p>
 * 描述：
 * </p>
 *
 * @author xiaovcloud
 * @since 2021/12/4 20:06
 */
public class UploadUtils {

    private final static UploadOssProperties UPLOAD_OSS_PROPERTIES =
            SpringContext.getBean(UploadOssProperties.class);

    /**
     * 上传文件到oos
     *
     * @param file 上传的文件
     * @return 访问地址path
     */
    public static String ossUpload(MultipartFile file, String targetPath, boolean isPrefix) {

        //获取文件名
        String originalFilename = file.getOriginalFilename();
        if (originalFilename == null) {
            throw new BizException("文件名不能为空！");
        }
        //获取文件后缀名
        String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);

        String fileName = getFileName(file, isPrefix);
        File tempFile = null;
        OSS ossClient = null;
        String fileUrl = "";
        try {
            tempFile = File.createTempFile(fileName, suffix);
            //MultipartFile  转换为 File
            file.transferTo(tempFile);
            ClientBuilderConfiguration config = new ClientBuilderConfiguration();
            //开启允许Cname
            config.setSupportCname(true);
            // 创建OSSClient实例。
            ossClient = new OSSClientBuilder().build(UPLOAD_OSS_PROPERTIES.getEndpoint(),
                    UPLOAD_OSS_PROPERTIES.getAccessKeyId(), UPLOAD_OSS_PROPERTIES.getAccessKeySecret(), config);
            //创建文件路径
            if (StrUtil.isNotEmpty(UPLOAD_OSS_PROPERTIES.getFileHost())) {
                fileUrl += UPLOAD_OSS_PROPERTIES.getFileHost() + File.separator;
            }
            fileUrl = targetPath + "/" + fileName;
            ossClient.putObject(new PutObjectRequest(UPLOAD_OSS_PROPERTIES.getBucketName(), fileUrl, tempFile));
        } catch (Exception e) {
            throw new BizException("上传阿里云OSS服务器异常:{}", e.getMessage());
        } finally {
            //关闭
            if (ossClient != null) {
                ossClient.shutdown();
            }
            //删除临时生成的文件
            if (tempFile != null && tempFile.exists()) {
                tempFile.deleteOnExit();
            }
        }
        return UPLOAD_OSS_PROPERTIES.getEndpoint() + "/" + fileUrl;
    }

    public static String localUpload(MultipartFile file, String targetPath, boolean isPrefix) {
        if (file == null || file.isEmpty()) {
            throw new BizException("上传文件未找到");
        }
        String fileName = getFileName(file, isPrefix);
        //创建对象文件目录
        File uploadDir = new File(targetPath);
        if (!uploadDir.exists()) {
            uploadDir.mkdirs();
        }
        File uploadFile = new File(uploadDir + File.separator + fileName);
        try {
            file.transferTo(uploadFile);
        } catch (IOException e) {
            throw new BizException("上传文件失败", e);
        }
        return fileName;
    }

    /**
     * 获取file生成新的文件名字
     *
     * @param file     上传服务器的文件
     * @param isPrefix 前缀标志位
     * @return 访问地址path
     */
    private static String getFileName(MultipartFile file, boolean isPrefix) {
        //获取文件名
        String originalFilename = file.getOriginalFilename();
        //获取文件前缀
        if (originalFilename == null) {
            throw new BizException("文件名不能为空！");
        }
        String prefix = originalFilename.substring(0, originalFilename.lastIndexOf("."));
        //获取文件后缀名
        String suffix = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
        if (isPrefix) {
            //使用时间作为文件名防止重复
            String newPrefix = DateUtil.format(new Date(), "yyyyMMddhhmmsss");
            return newPrefix + "_" + prefix + "." + suffix;
        } else {
            return prefix + "." + suffix;
        }
    }
}
